package com.example.springbootmybatisplus.annotation;

import com.example.springbootmybatisplus.utils.MaskUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;

/**
 * @ClassName SensitiveAspect
 * @Description: TODO
 * @Author: Sunny
 * @Create: 2023-12-26 10:13
 * @Version 1.0
 **/

@Aspect
@Configuration
public class SensitiveAspect {
    public static final String ACCESS_EXECUTION = "execution(* com.example..*.*(..))";
    /**
     * 注解脱敏处理
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around(ACCESS_EXECUTION)
    public Object sensitiveClass(ProceedingJoinPoint joinPoint) throws Throwable {
        return sensitiveFormat(joinPoint);
    }

    /**
     * 插拔式注解统一拦截器。@SensitiveField
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    public Object sensitiveFormat(ProceedingJoinPoint joinPoint) throws Throwable {
        Object obj = joinPoint.proceed();
        if (obj == null || isPrimitive(obj.getClass())) {
            return obj;
        }
        for (Field field : obj.getClass().getDeclaredFields()) {
            ReflectionUtils.makeAccessible(field);
            SensitiveField sensitiveField = field.getAnnotation(SensitiveField.class);
            if (sensitiveField != null) {
                Object value = field.get(obj);
                switch (sensitiveField.value()) {
                    case IDCARD:
                        String idCard = MaskUtil.maskIdCard((String) value);
                        ReflectionUtils.setField(field, obj, idCard);
                        break;
                    case PHONE:
                        String phone = MaskUtil.maskPhone((String) value);
                        ReflectionUtils.setField(field, obj, phone);
                        break;
                    case NAME:
                        String name = MaskUtil.chineseName((String) value);
                        ReflectionUtils.setField(field, obj, name);
                        break;
                    case ADDRESS:
                        //TODO
                        String address = MaskUtil.address((String) value, StringUtils.length((String) value));
                        ReflectionUtils.setField(field, obj, address);
                        break;
                    case BANK:
                        //TODO
                        String bankCard = MaskUtil.bankCard((String) value);
                        ReflectionUtils.setField(field, obj, bankCard);
                        break;
                    case CARLICENSE:
                        //TODO
                        String carLicense = MaskUtil.carLicense((String) value);
                        ReflectionUtils.setField(field, obj, carLicense);
                        break;
                    default:
                        break;
                }
            }
        }
        return obj;
    }


    /**
     * 基本数据类型和String类型判断
     *
     * @param clz
     * @return
     */
    private boolean isPrimitive(Class<?> clz) {
        try {
            if (String.class.isAssignableFrom(clz) || clz.isPrimitive()) {
                return true;
            } else {
                return ((Class) clz.getField("TYPE").get(null)).isPrimitive();
            }
        } catch (Exception e) {
            return false;
        }
    }


}